home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Modules
/
do-macs.em
< prev
next >
Wrap
Lisp/Scheme
|
1992-10-06
|
5KB
|
236 lines
; simple C-like loop macros
;
; (for initial test iteration form form ... )
; value is the value of the last form
;
; (while test form form ... )
; value is the value of the last form
;
; (do form form ... form (while test))
; value is the value of the last form
; implicit progn in while clause
;
; (break form form ... )
; exit the innermost loop, returning the value of the last form
;
; (continue)
; skip to the end of the innermost loop
; (setq |@loopy-final-value@| ... ) should be
; (setq |@loopy-final-value@| (values ... ))
(defmodule do-macs
(standard trace)
()
(defmacro for (init test iter . body)
`(progn ,init
(while ,test
,@body
,iter)))
(export for)
(defun map-range (f s e)
(if (> s e) ()
(progn
(f s)
(map-range f (+ s 1) e))))
(defmacro dotimes (var start end . body)
`(map-range
(lambda (,var) ,@body)
,start ,end))
(export map-range dotimes)
(defmacro ++ (form . vals)
(cond ((atom form)
`(setq ,form (+ ,form 1)))
((eq (car form) 'dynamic)
`(dynamic-setq ,(cadr form) (+ ,form 1)))
(t
`((setter ,(car form)) ,(cadr form) (+ ,form 1)))))
(defmacro -- (form)
(cond ((atom form)
`(setq ,form (- ,form 1)))
((eq (car form) 'dynamic)
`(dynamic-setq ,(cadr form) (- ,form 1)))
(t
`((setter ,(car form)) ,(cadr form) (- ,form 1)))))
(export ++ --)
(defmacro setf (form val)
(cond ((atom form)
`(setq ,form ,val))
((eq (car form) 'dynamic)
`(dynamic-setq ,(cadr form) ,val))
(t
`(let ((@-woo-woo-@ ,val))
((setter ,(car form)) ,@(cdr form) @-woo-woo-@)
@-woo-woo-@))))
(export setf)
(defmacro break forms
`(@break-cont@ (progn ,@forms)))
(defmacro continue ()
`(@continue-cont@ '(() t)))
(defmacro while (pred . forms)
`(let/cc @break-cont@
(map-while (lambda (@continue-cont@) ,@forms)
(lambda () ,pred)
())))
(defun map-while (ff pf val)
(let ((ans (let/cc cc (map-while-cont ff pf cc val))))
(if (cdr ans)
(map-while ff pf val)
(car ans))))
(defun map-while-cont (ff pf cc val)
(if (pf)
(map-while-cont ff pf cc (ff cc))
(cons val ())))
(defmacro docdr (var arglis . body)
`(when (not (null ,arglis))
(let ((,var ,arglis)
(rest (cdr ,arglis)))
(while ,var
(when ,var
,@body
(if rest
(progn
(setq ,var rest)
(setq rest (cdr rest)))
(setq ,var nil)))))))
(export docdr)
(defmacro docollect (var arg-lis . body)
`(when (not (null ,arg-lis))
(let ((,var (car ,arg-lis))
(rest (cdr ,arg-lis))
(new-lis nil))
(while ,var
(when ,var
(setq new-lis (append new-lis (list (progn ,@body))))
(if rest
(progn
(setq ,var (car rest))
(setq rest (cdr rest)))
(setq ,var nil))))
new-lis)))
(export docollect)
(defmacro docollect-unique (var arg-lis . body)
`(when (not (null ,arg-lis))
(let ((,var (car ,arg-lis))
(rest (cdr ,arg-lis))
(new-lis nil)
(temp nil))
(while ,var
(when (not (memq (setq temp (progn ,@body)) new-lis))
(setq new-lis (append new-lis (list temp))))
(if rest
(progn
(setq ,var (car rest))
(setq rest (cdr rest)))
(setq ,var nil)))
new-lis)))
(export docollect-unique)
;; List macros...
(defmacro push (val st) `(setq ,st (cons ,val ,st)))
(defmacro pop (st) `(let ((val (car ,st)))
(setq ,st (cdr ,st))
val))
(export push pop)
(defmacro incf (arg)
`(setq ,arg (+ 1 ,arg)))
(export incf)
(defmacro decf (arg)
`(setq ,arg (- ,arg 1)))
(export decf)
(defmacro trap (value . forms)
`(let/cc escape
(with-handler (lambda (a b) (escape ,value)) ,@forms)))
(export trap)
(defmacro multiple-setq forms
(if forms
`(progn
(setq ,(car forms) ,(cadr forms))
(multiple-setq ,@(cddr forms)))
`(progn nil)))
(export multiple-setq)
(defmacro dolist (var arglist . body)
`(mapc (lambda (,var) ,@body) ,arglist))
(export dolist)
(defmacro do* (control test-result . body)
(let ((decl nil) (label (gensym)) (vl nil) (step nil)
(test (car test-result))
(result (cdr test-result)))
(mapc (lambda (c)
(when (symbolp c) (setq c (list c)))
(setq vl (cons (list (car c) (cadr c)) vl))
(unless (not (consp (cddr c)))
(setq step (cons (car c) step))
(setq step (cons (caddr c) step))))
control)
`(let* ,(reverse vl)
; ,@decl
(while (not ,test)
(progn ,@body)
(multiple-setq ,@(reverse step)))
(progn ,@result))))
(export do*)
(export break continue while map-while map-while-cont)
(defmacro prog x `(progn ,@x))
(export prog)
(defmacro do body
(let* ((revbody (reverse body))
(while-clause (car revbody))
(test (if (and (consp while-clause)
(eq (car while-clause) 'while))
(cdr while-clause)
(list while-clause)))
(newbody (reverse (cdr revbody))))
`(let ((@-res-@ nil))
(while (progn (setq @-res-@ (progn ,@newbody))
(progn ,@test))
nil)
@-res-@)))
(export do)
)